package com.rm;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import sun.misc.BASE64Encoder;

import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

public class SignUtil extends Thread {
    private static final Log log = LogFactory.getLog(SignUtil.class);

    public static String getParam(String headParam, Map<String, String> paramMap, String endParam, String pairsFlag, String signKey) throws Exception {
        log.debug("开始拼接参数信息...");

        StringBuilder paramBuilder = new StringBuilder();

        // 对入参Map排序并拼接

        for (Map.Entry<String, String> m : paramMap.entrySet()) {
            log.debug("Param参数信息-" + m.getKey() + ":" + m.getValue());
            paramBuilder.append(m.getKey()).append("=").append(m.getValue()).append("&");
        }

        // 获取参数拼接信息
        String paramNVP = getParamNVP(headParam, paramMap, endParam, pairsFlag);

        // 获取签名信息
        String signV = getSign(paramNVP);

        // 添加参数字符串尾部
        paramBuilder.append(signKey).append("=").append(signV);

        log.info("返回拼接Param串:" + paramBuilder.toString());

        return paramBuilder.toString();

    }

    public static String getParamNVP(String headParam, Map<String, String> paramMap, String endParam, String pairsFlag) throws Exception {
        log.debug("开始拼接参数NVP信息...");

        StringBuilder paramNVPBuilder = new StringBuilder();

        // 添加参数字符串头部
        if (endParam != null || endParam.length() > 0) {
            paramNVPBuilder.append(headParam);
        }

        // 对入参Map排序并拼接
        List<Map.Entry<String, String>> lstEntry = new ArrayList<>(paramMap.entrySet());
        Collections.sort(lstEntry, ((o1, o2) -> {
            return o1.getKey().compareTo(o2.getKey());
        }));
        lstEntry.forEach(o -> {
            log.debug("NVP参数信息-" + o.getKey() + ":" + o.getValue());
            if (paramNVPBuilder == null || paramNVPBuilder.length() <= 0) {
                paramNVPBuilder.append(o.getKey()).append("=").append(o.getValue());
            } else {
                paramNVPBuilder.append(pairsFlag).append(o.getKey()).append("=").append(o.getValue());
            }
        });

        // 添加参数字符串尾部
        if (endParam != null || endParam.length() > 0) {
            paramNVPBuilder.append(pairsFlag).append(endParam);
        }

        log.info("返回拼接ParamNVP值:" + paramNVPBuilder.toString());

        return paramNVPBuilder.toString();

    }

    public static String getSign(String paramv) throws Exception {
        log.debug("ParamNVP进行MD5(32)加密...");

        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(paramv);
        String result = SignUtil.encodeMD5String(stringBuilder.toString());

        log.debug("ParamNVP MD5后的值:" + result);

        return result;

    }

    public static final String EncoderPwdByMd5(String str) throws NoSuchAlgorithmException, UnsupportedEncodingException {
        // 确定计算方法
        MessageDigest md5 = MessageDigest.getInstance("MD5");
        BASE64Encoder base64en = new BASE64Encoder();
        // 加密后的字符串
        String newstr = base64en.encode(md5.digest(str.getBytes("utf-8")));
        return newstr;
    }

    public static String encodeMD5String(String plainText) {
        StringBuffer buf = new StringBuffer("");
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(plainText.getBytes());
            byte b[] = md.digest();
            int i;

            for (int offset = 0; offset < b.length; offset++) {
                i = b[offset];
                if (i < 0)
                    i += 256;
                if (i < 16)
                    buf.append("0");
                buf.append(Integer.toHexString(i));
            }
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return buf.toString();
    }
}